/*
	Author: Freddo, Edited by Genesis

	Description:
		Function for improving AI driving. AI drivers will avoid obstacles and units BETTER with this, at the cost of FPS.

	Parameter(s):
		0: ARRAY - Array containing drivers to affect

	Returns:
		NOTHING
	Example1:  driverArray spawn VCM_fnc_VehicleDetection;
*/

//This script aims to improve AI driving skills...It's basic. But it works.
{
	private _PredictPos = [_x,3] call VCM_fnc_MovePrediction;
	_PredictPos set [2,0.1];
	if (VCM_Debug) then 
	{
		_PredictPos spawn 
		{
			private _arrow = "Sign_Arrow_Cyan_F" createVehicleLocal [0,0,0];_arrow setPos _this;sleep 2;deleteVehicle _arrow;
		};
	};
	
	//Lets check for obstacles and make sure the vehicle does not hit them
	//Create an array of objects near predicted path
	private _obstacles = _predictPos nearObjects ["ALL", VCM_DrivingDist]; // VCM_DrivingDist is search distance
	
	
	//Remove gates, bridges and units vehicle from obstacles
	private _RemoveArray = [];
	private _veh = objectParent _x;
	{
		if (_veh isEqualTo _x || {_x isKindOf "AllVehicles"} || {["gate",(str _x)] call BIS_fnc_inString} || {["bridge",(str _x)] call BIS_fnc_inString}) then
		{
			_RemoveArray pushback _x; //We do this method to avoid indexing errors.
		};
	} forEach _obstacles;
	
	//We do this method to avoid indexing errors.
	{
		private _Obj = _x;
		private _idx = -1;
		{if(_x isEqualTo _Obj)exitWith{_idx=_forEachIndex}} forEach _obstacles;
		_obstacles deleteAt _idx;
	} foreach _RemoveArray;
	
	private _hlprArray = [];

	{
		
		if !(_x getVariable ["VCM_AVOID", false] || {_x isKindOf "man"} || {_x isKindOf "Helper_Base_F"} || {_x isKindOf "Logic"}) then 
		{
			// Vcom ignore this object until loop complete
			_x setVariable ["VCM_AVOID", true];
			
			// Positions to spawn helper objects
			private _hlpPosArray = [];
			
			private _boundBox = boundingBoxReal _x;
			private _p2 = _boundBox select 1;
			
			_p2 params ["_p2MaxX","_p2MaxY","_p2MaxZ"];
			
			// Find corners of building bounding box
			_hlpPosArray pushBack (_x modelToWorld [_p2MaxX,_p2MaxY,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [-_p2MaxX,_p2MaxY,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [-_p2MaxX,-_p2MaxY,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [_p2MaxX,-_p2MaxY,-_p2MaxZ + 0.1]);
			// Get mid points of a building.
			_hlpPosArray pushBack (_x modelToWorld [0,-_p2MaxY,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [0,_p2MaxY,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [-_p2MaxX,0,-_p2MaxZ + 0.1]);
			_hlpPosArray pushBack (_x modelToWorld [_p2MaxX,0,-_p2MaxZ + 0.1]);
			
			// Spawn helper objects (These act as additional points of contact that the AI will attempt to avoid)
			{
				if ([_hlprArray, _x, true,"Driving"] call VCM_fnc_ClstObj distance2D _x > 1) then
				{
					private _hlpObj = "Steel_Plate_S_F" createVehicleLocal _x;
					_hlpObj setVariable ["VCM_AVOID", true];
					_hlpObj setPos _x;
					_hlpObj setDamage 1;
					_hlpObj setObjectTextureGlobal [0, ""];
					_hlprArray pushBack _hlpObj;
				};
			} forEach _hlpPosArray;
			
			//Spawn debug objects
			if (VCM_Debug) then
			{
				
				{
					private _ObjPos = getpos _x;
					[_ObjPos select 0, _ObjPos select 1, 0.2] spawn 
					{
						private _arrow = "Sign_Arrow_Large_F" createVehicle [0,0,0];
						_arrow setPos _this;
						sleep 9;
						deleteVehicle _arrow;
					};
					
				} forEach _hlprArray;
				
			};
		

			// Delete helper objects after some time
			[_hlprArray, _obstacles] spawn 
			{
				sleep 9;
				{
					deleteVehicle _x;
				} forEach (_this select 0);
				{
					// Allow object to be considered again
					_x setVariable ["VCM_AVOID", false];
				} forEach (_this select 1);
				
			};
		
		};
		
	} forEach _obstacles;
	
	
	
	//Avoid units.
	private _Livingobstacles = _predictPos nearObjects ["MAN", 25];
	private _Unit = _x;
	private _idex = -1;
	{if(_x isEqualTo _Unit)exitWith{_idex=_forEachIndex}} forEach _Livingobstacles;
	_LivingObstacles deleteAt _idex; 
	
	private _NearestUnit = [_Livingobstacles, _x, true,"Driving"] call VCM_fnc_ClstObj;
	if (_NearestUnit distance2D _x < 50) then
	{
		private _hlpObj = "Steel_Plate_S_F" createVehicleLocal [0,0,0];
		_hlpObj setDamage 1;
		_hlpObj setVariable ["VCM_AVOID", true];
		_hlpObj setPos (getpos _NearestUnit);
		_hlpObj setObjectTextureGlobal [0, ""];
		_hlpObj spawn {sleep 2; deletevehicle _this};
	};
	
} foreach _this;